home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / netprog.zip / NETPROG.TAR / tftp / cmdsubr.c < prev    next >
C/C++ Source or Header  |  1989-12-17  |  4KB  |  191 lines

  1. /*
  2.  * Miscellaneous functions for user command processing.
  3.  */
  4.  
  5. #include    "cmd.h"
  6.  
  7.     /* all of the following functions are in cmd.c */
  8. int    cmd_ascii(), cmd_binary(), cmd_connect(), cmd_exit(),
  9.     cmd_get(), cmd_help(), cmd_mode(), cmd_put(),
  10.     cmd_status(), cmd_trace(), cmd_verbose();
  11.  
  12. Cmds    commands[] = {    /* keep in alphabetical order for binary search */
  13.         "?",        cmd_help,
  14.         "ascii",    cmd_ascii,
  15.         "binary",    cmd_binary,
  16.         "connect",    cmd_connect,
  17.         "exit",        cmd_exit,
  18.         "get",        cmd_get,
  19.         "help",        cmd_help,
  20.         "mode",        cmd_mode,
  21.         "put",        cmd_put,
  22.         "quit",     cmd_exit,
  23.         "status",    cmd_status,
  24.         "trace",    cmd_trace,
  25.         "verbose",    cmd_verbose,
  26. };
  27. #define    NCMDS    (sizeof(commands) / sizeof(Cmds))
  28.  
  29. int    ncmds = NCMDS;
  30.  
  31. static char    line[MAXLINE] = { 0 };
  32. static char    *lineptr = NULL;
  33.  
  34. /*
  35.  * Fetch the next command line.
  36.  * For interactive use or batch use, the lines are read from a file.
  37.  *
  38.  * Return 1 if OK, else 0 on error or end-of-file.
  39.  */
  40.  
  41. int
  42. getline(fp)
  43. FILE    *fp;
  44. {
  45.     if (fgets(line, MAXLINE, fp) == NULL)
  46.         return(0);        /* error or end-of-file */
  47.     lineptr = line;
  48.  
  49.     return(1);
  50. }
  51.  
  52. /*
  53.  * Fetch the next token from the input stream.
  54.  * We use the line that was set up in the most previous call to
  55.  * getline().
  56.  *
  57.  * Return a pointer to the token (the argument), or NULL if no more exist.
  58.  */
  59.  
  60. char *
  61. gettoken(token)
  62. char    token[];
  63. {
  64.     register int    c;
  65.     register char    *tokenptr;
  66.  
  67.     while ((c = *lineptr++) == ' ' || c == '\t')
  68.         ;        /* skip leading white space */
  69.  
  70.     if (c == '\0' || c == '\n')
  71.         return(NULL);    /* nothing there */
  72.  
  73.     tokenptr = token;
  74.     *tokenptr++ = c;    /* first char of token */
  75.  
  76.     /*
  77.      * Now collect everything up to the next space, tab, newline, or null.
  78.      */
  79.  
  80.     while ((c = *lineptr++) != ' ' && c != '\t' && c != '\n' && c != '\0')
  81.         *tokenptr++ = c;
  82.  
  83.     *tokenptr = 0;        /* null terminate token */
  84.     return(token);
  85. }
  86.  
  87. /*
  88.  * Verify that there aren't any more tokens left on a command line.
  89.  */
  90.  
  91. checkend()
  92. {
  93.     if (gettoken(temptoken) != NULL)
  94.         err_cmd("trailing garbage");
  95. }
  96.  
  97. /*
  98.  * Execute a command.
  99.  * Call the appropriate function.  If all goes well, that function will
  100.  * return, otherwise that function may call an error handler, which will
  101.  * call longjmp() and branch back to the main command processing loop.
  102.  */
  103.  
  104. docmd(cmdptr)
  105. char    *cmdptr;
  106. {
  107.     register int    i;
  108.  
  109.     if ( (i = binary(cmdptr, ncmds)) < 0)
  110.         err_cmd(cmdptr);
  111.  
  112.     (*commands[i].cmd_func)();
  113.  
  114.     checkend();
  115. }
  116.  
  117. /*
  118.  * Perform a binary search of the command table
  119.  * to see if a given token is a command.
  120.  */
  121.  
  122. binary(word, n)
  123. char    *word;
  124. int    n;
  125. {
  126.     register int    low, high, mid, cond;
  127.  
  128.     low  = 0;
  129.     high = n - 1;
  130.     while (low <= high) {
  131.         mid = (low + high) / 2;
  132.         if ( (cond = strcmp(word, commands[mid].cmd_name)) < 0)
  133.             high = mid - 1;
  134.         else if (cond > 0)
  135.             low = mid + 1;
  136.         else
  137.             return(mid);    /* found it, return index in array */
  138.     }
  139.     return(-1);    /* not found */
  140. }
  141.  
  142. /*
  143.  * Take a "host:file" character string and separate the "host"
  144.  * portion from the "file" portion.
  145.  */
  146.  
  147. striphost(fname, hname)
  148. char    *fname;        /* input:  "host:file" or just "file" */
  149. char    *hname;        /* store "host" name here, if present */
  150. {
  151.     char        *index();
  152.     register char    *ptr1, *ptr2;
  153.  
  154.     if ( (ptr1 = index(fname, ':')) == NULL)
  155.         return;        /* there is not a "host:" present */
  156.  
  157.     /*
  158.      * Copy the entire "host:file" into the hname array,
  159.      * then replace the colon with a null byte.
  160.      */
  161.  
  162.     strcpy(hname, fname);
  163.     ptr2 = index(hname, ':');
  164.     *ptr2 = 0;    /* null terminates the "host" string */
  165.  
  166.     /*
  167.      * Now move the "file" string left in the fname array,
  168.      * removing the "host:" portion.
  169.      */
  170.  
  171.     strcpy(fname, ptr1 + 1);    /* ptr1 + 1 to skip over the ':' */
  172. }
  173.  
  174. /*
  175.  * User command error.
  176.  * Print out the command line too, for information.
  177.  */
  178.  
  179. err_cmd(str)
  180. char    *str;        /* may be a 0-length string, i.e., "" */
  181. {
  182.     fprintf(stderr, "%s: '%s' command error", pname, command);
  183.     if (strlen(str) > 0)
  184.         fprintf(stderr, ": %s", str);
  185.     fprintf(stderr, "\n");
  186.     fflush(stderr);
  187.  
  188.     longjmp(jmp_mainloop, 1);    /* 1 -> not a timeout, we've already
  189.                        printed our error message */
  190. }
  191.